# from urllib.parse import urlencode, parse_qs
# from urllib.request import urlopen
# import logging
# from .exceptions import QQException
# import json
# from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,BadData
# from django.conf import settings
# from .constants import SAVE_QQ_USER_TOKEN_EXPIRES
#
# logger = logging.getLogger('django')
#
#
# class OAuthQQ(object):
#     def __init__(self, client_id=None, client_secret=None, redirect_uri=None):
#         self.client_id = client_id or settings.QQ_CLIENT_ID
#         self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URI
#         self.client_secret = client_secret or settings.QQ_CLIENT_SECRET
#
#     def get_qq_login_url(self, state):
#         params = {
#             'response_type': 'code',
#             'client_id': self.client_id,
#             'redirect_uri': self.redirect_uri,
#             'state': state or settings.QQ_STATE,
#             'scope': 'get_user_info',
#         }
#         url = 'https://graph.qq.com/oauth2.0/authorize?'
#         url += urlencode(params)
#         return url
#
#     def get_qq_access_token(self, code=None):
#         params = {
#             'grant_type': 'authorization_code',
#             'client_id': self.client_id,
#             'client_secret': self.client_secret,
#             'code': code,
#             'redirect_uri': self.redirect_uri
#         }
#         url = 'https://graph.qq.com/oauth2.0/token?'
#         url += urlencode(params)
#         # 向qq服务器发送请求
#         try:
#             response = urlopen(url)
#             response_str = response.read().decode()
#             # 获取qq服务器返回的access_token
#             response_dict = parse_qs(response_str)
#             access_token = response_dict.get('access_token')[0]
#         except QQException as e:
#             logger.error(e)
#             raise QQException
#         return access_token
#
#     @staticmethod
#     def get_qq_openid(access_token=None):
#         params = {
#             'access_token': access_token
#         }
#         url = 'https://graph.qq.com/oauth2.0/me?'
#         url += urlencode(params)
#         # 向qq服务器发送请求
#         response_str = ''
#         try:
#             response = urlopen(url)
#             response_str = response.read().decode()
#             response_dict = json.loads(response_str[10:-4])
#             openid = response_dict.get('openid')
#         except QQException as e:
#             logger.error(e)
#             error_dict = parse_qs(response_str)
#             return 'code:%s,msg:%s' % (error_dict.get('code'), error_dict.get('msg'))
#
#         return openid
#
#     @staticmethod
#     def generate_user_token(openid):
#         s = Serializer(settings.SECRET_KEY, expires_in=SAVE_QQ_USER_TOKEN_EXPIRES)
#         data = {'openid':openid}
#         token =s.dumps(data)
#         return token.decode()
#
#     @staticmethod
#     def check_save_user_token(token):
#         """
#         检验保存用户数据的token
#         :param token:
#         :return: openid or None
#         """
#         s = Serializer(settings.SECRET_KEY,expires_in=SAVE_QQ_USER_TOKEN_EXPIRES)
#         try:
#             # 字符串转成字典
#             data = s.loads(token)
#         except BadData:
#             return None
#         else:
#             return data.get('openid')
from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData
from django.conf import settings
import json
import logging
from .exceptions import QQAPIError
from . import constants

logger = logging.getLogger('django')


class OAuthQQ(object):
    """
    QQ认证辅助工具类
    """
    def __init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):
        self.client_id = client_id or settings.QQ_CLIENT_ID
        self.client_secret = client_secret or settings.QQ_CLIENT_SECRET
        self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URI
        self.state = state or settings.QQ_STATE  # 用于保存登录成功后的跳转页面路径

    def get_qq_login_url(self):
        """
        获取qq登录的网址
        :return: url网址
        """
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': self.state,
            'scope': 'get_user_info',
        }
        url = 'https://graph.qq.com/oauth2.0/authorize?' + urlencode(params)
        return url

    def get_access_token(self, code):
        """
        获取access_token
        :param code: qq提供的code
        :return: access_token
        """
        params = {
            'grant_type': 'authorization_code',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'code': code,
            'redirect_uri': self.redirect_uri
        }
        url = 'https://graph.qq.com/oauth2.0/token?' + urlencode(params)
        response = urlopen(url)
        response_data = response.read().decode()
        data = parse_qs(response_data)
        access_token = data.get('access_token', None)
        if not access_token:
            logger.error('code=%s msg=%s' % (data.get('code'), data.get('msg')))
            raise QQAPIError

        return access_token[0]

    def get_openid(self, access_token):
        """
        获取用户的openid
        :param access_token: qq提供的access_token
        :return: open_id
        """
        url = 'https://graph.qq.com/oauth2.0/me?access_token=' + access_token
        response = urlopen(url)
        response_data = response.read().decode()
        try:
            # 返回的数据 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )\n;
            data = json.loads(response_data[10:-4])
        except Exception:
            data = parse_qs(response_data)
            logger.error('code=%s msg=%s' % (data.get('code'), data.get('msg')))
            raise QQAPIError
        openid = data.get('openid', None)
        return openid

    @staticmethod
    def generate_save_user_token(openid):
        """
        生成保存用户数据的token
        :param openid: 用户的openid
        :return: token
        """
        serializer = Serializer(settings.SECRET_KEY, expires_in=constants.SAVE_QQ_USER_TOKEN_EXPIRES)
        data = {'openid': openid}
        token = serializer.dumps(data)
        return token.decode()

    @staticmethod
    def check_save_user_token(token):
        """
        检验保存用户数据的token
        :param token: token
        :return: openid or None
        """
        serializer = Serializer(settings.SECRET_KEY, expires_in=constants.SAVE_QQ_USER_TOKEN_EXPIRES)
        try:
            data = serializer.loads(token)
        except BadData:
            return None
        else:
            return data.get('openid')